package santiago.view;

import java.awt.Component;
import javax.swing.JOptionPane;
import santiago.client.Client;
import santiago.view.game.FrameGame;
import santiago.view.lobby.DialogCreateGame;
import santiago.view.lobby.DialogJoinGame;
import santiago.view.lobby.FrameServerMenu;
import santiago.view.menu.DialogAbout;
import santiago.view.menu.DialogHowToPlay;
import santiago.view.menu.DialogJoinServer;
import santiago.view.menu.DialogPlayerStatistics;
import santiago.view.menu.FrameConnection;
import santiago.view.menu.FrameMainMenu;

/**
 * Helps to manage all
 * <code>ISantiagoFrame</code>
 */
public final class SantiagoFrameManager {

    /**
     * All frames
     */
    //-------------Other
    private FrameConnection FrameConnection;
    private FrameMainMenu FrameMainMenu;
    private FrameServerMenu FrameServerMenu;
    private DialogJoinServer DialogJoinServer;
    private DialogCreateGame DialogCreateGame;
    private DialogJoinGame DialogJoinGame;
    private DialogPlayerStatistics DialogPlayerStatistics;
    private DialogHowToPlay DialogHowToPlay;
    private DialogAbout DialogAbout;
    //-------------Game
    private FrameGame FrameGame;
    /**
     * Current client frame
     */
    private ISantiagoFrame Pointer;

    /**
     * Constructor
     */
    public SantiagoFrameManager() {
        setFrameConnection(new FrameConnection());
        setPointer(FrameConnection);
        FrameConnection.printIt();
        new ResourceManager();
        //Music.Menu.play();
    }

    /**
     * Utility methods
     */
    public void closeDialog() {
        switch (Pointer.getClass().getName()) {
            case "santiago.view.menu.DialogJoinServer":
                Pointer.hideIt();
                setPointer(FrameMainMenu);
                break;
            case "santiago.view.lobby.DialogCreateGame":
                Pointer.hideIt();
                setPointer(FrameServerMenu);
                FrameServerMenu.refresh();
                break;
        }
    }

    public void authentication(String Login, String Password) {
        FrameConnection.hideIt();
        setFrameMainMenu(new FrameMainMenu(Login));
        setPointer(FrameMainMenu);
        FrameMainMenu.printIt();
    }

    public void joinServer() {
        setDialogJoinServer(new DialogJoinServer(FrameMainMenu, true));
        setPointer(DialogJoinServer);
        DialogJoinServer.printIt();
    }

    public void connect() {
        DialogJoinServer.hideIt();
        FrameMainMenu.hideIt();
        setFrameServerMenu(new FrameServerMenu());
        setPointer(FrameServerMenu);
        FrameServerMenu.printIt();
    }

    public void disconnect(String Login) {
        FrameServerMenu.hideIt();
        setFrameMainMenu(new FrameMainMenu(Login));
        setPointer(FrameMainMenu);
        FrameMainMenu.printIt();
    }

    public void createGame() {
        setDialogCreateGame(new DialogCreateGame(FrameServerMenu, true));
        setPointer(DialogCreateGame);
        DialogCreateGame.printIt();
    }

    public void createGameConfirm() {
        DialogCreateGame.hideIt();
    }

    public void joinGame(String GameName) {
        setDialogJoinGame(new DialogJoinGame(FrameServerMenu, true, GameName));
        setPointer(DialogJoinGame);
        DialogJoinGame.printIt();
    }

    public void leaveGame() {
        DialogJoinGame.hideIt();
        setPointer(FrameServerMenu);
        FrameServerMenu.refresh();
    }

    public void initGame() {
        DialogJoinGame.initStart();
        //Music.Menu.pause();
    }

    public void startGame() {
        DialogJoinGame.hideIt();
        FrameServerMenu.hideIt();
        setFrameGame(new FrameGame());
        setPointer(FrameGame);
        FrameGame.printIt();
        //Music.Game.play();
    }

    public void aboardGame() {
        try {
            errorDialog("Un joueur a quitté le jeu, partie annulée.");
            FrameGame.hideIt();
            setFrameServerMenu(new FrameServerMenu());
            setPointer(FrameServerMenu);
            FrameServerMenu.printIt();
            //Music.Menu.play();
        } catch (Exception e) {
            System.exit(0);
        }
    }

    public void displayMessage(String Message) {
        while (FrameGame == null) {
            Thread.yield();
        }
        FrameGame.displayMessage(Message);
    }

    public void connectionLost(String Login) {
        errorDialog("La connexion a été perdue");
        disconnect(Login);
    }

    public void refresh() {
        getPointer().refresh();
    }

    /**
     * Exceptions handler
     */
    public void handleException(Exception e) {
        switch (e.getClass().getName()) {
            case "santiago.exception.EmptyFieldException":
                errorDialog("Un ou plusieurs champs ne sont pas renseignés");
                break;
            case "santiago.exception.IPAddressPatternException":
                errorDialog("L'adresse IP n'est pas au bon format");
                break;
            case "santiago.exception.RemoteException":
                if (Pointer instanceof DialogJoinServer) {
                    errorDialog("Impossible de se connecter au serveur");
                } else {
                    errorDialog("Vous avez perdu la connexion avec le serveur");
                }
                authentication(Client.getLogin(), null);
                break;
            case "java.rmi.ConnectException":
                errorDialog("Impossible de se connecter au serveur");
                break;
            case "santiago.exception.AlreadyInGameException":
                break;
            case "santiago.exception.ExistingItemException":
                if (Pointer instanceof DialogCreateGame) {
                    errorDialog("Ce nom de partie existe déjà.");
                } else if (Pointer instanceof FrameConnection || Pointer instanceof DialogJoinServer) {
                    errorDialog("Ce pseudo est déjà utilisé");
                }
                break;
            case "santiago.exception.MaximalPlayerCountReachedException":
                break;
            case "santiago.exception.NoSuchGameException":
                errorDialog("La partie n'existe plus !");
                break;
            case "santiago.exception.NotInGameException":
                break;
            case "java.lang.NumberFormatException":
                errorDialog("Vous devez spécifier un entier !");
                break;
            case "santiago.exception.InvalidAmountException":
                errorDialog("Montant incorrect !");
                break;
            case "santiago.exception.NotEnoughCashException":
                errorDialog("Vous n'avez pas assez d'escudos !");
                break;
            default:
                errorDialog("Une erreur est survenue : " + e.getMessage());
        }
    }

    private void errorDialog(String msg) {
        JOptionPane.showMessageDialog((Component) Pointer, msg, "Erreur", JOptionPane.ERROR_MESSAGE);
    }

    /**
     * Getters & Setters
     */
    public FrameConnection getFrameConnection() {
        return FrameConnection;
    }

    public void setFrameConnection(FrameConnection FrameConnection) {
        this.FrameConnection = FrameConnection;
    }

    public FrameMainMenu getFrameMainMenu() {
        return FrameMainMenu;
    }

    public void setFrameMainMenu(FrameMainMenu FrameMainMenu) {
        this.FrameMainMenu = FrameMainMenu;
    }

    public FrameServerMenu getFrameServerMenu() {
        return FrameServerMenu;
    }

    public void setFrameServerMenu(FrameServerMenu FrameServerMenu) {
        this.FrameServerMenu = FrameServerMenu;
    }

    public DialogJoinServer getDialogJoinServer() {
        return DialogJoinServer;
    }

    public void setDialogJoinServer(DialogJoinServer DialogJoinServer) {
        this.DialogJoinServer = DialogJoinServer;
    }

    public DialogCreateGame getDialogCreateGame() {
        return DialogCreateGame;
    }

    public void setDialogCreateGame(DialogCreateGame DialogCreateGame) {
        this.DialogCreateGame = DialogCreateGame;
    }

    public DialogJoinGame getDialogJoinGame() {
        return DialogJoinGame;
    }

    public void setDialogJoinGame(DialogJoinGame DialogJoinGame) {
        this.DialogJoinGame = DialogJoinGame;
    }

    public DialogPlayerStatistics getDialogPlayerStatistics() {
        return DialogPlayerStatistics;
    }

    public void setDialogPlayerStatistics(DialogPlayerStatistics DialogPlayerStatistics) {
        this.DialogPlayerStatistics = DialogPlayerStatistics;
    }

    public DialogHowToPlay getDialogHowToPlay() {
        return DialogHowToPlay;
    }

    public void setDialogHowToPlay(DialogHowToPlay DialogHowToPlay) {
        this.DialogHowToPlay = DialogHowToPlay;
    }

    public DialogAbout getDialogAbout() {
        return DialogAbout;
    }

    public void setDialogAbout(DialogAbout DialogAbout) {
        this.DialogAbout = DialogAbout;
    }

    public FrameGame getFrameGame() {
        return FrameGame;
    }

    public void setFrameGame(FrameGame FrameGame) {
        this.FrameGame = FrameGame;
    }

    public ISantiagoFrame getPointer() {
        return Pointer;
    }

    public void setPointer(ISantiagoFrame Pointer) {
        this.Pointer = Pointer;
    }
}
